package com.franklin.java.utils;

import com.franklin.java.api.annotation.BaseAnnotation;
import com.franklin.java.api.mybatis.mybatisplus.annotation.MPAnnotations;
import com.franklin.java.api.psi.comment.PsiCommentResolverFactory;
import com.franklin.java.entity.sql.ColumnInfo;
import com.franklin.plugins.common.collection.PrettyArrayList;
import com.franklin.plugins.common.utils.DataCheckUtils;
import com.franklin.plugins.common.utils.StringHelper;
import com.intellij.psi.*;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.util.PsiTreeUtil;

import java.util.List;
import java.util.Optional;

/**
 * 解析实体类工具类
 * @author Franklin
 * @since 2021/9/2 12:08
 */
public class EntityClassHelper {


    /**
     * 解析实体里面的属性<br>
     * @author Franklin
     * @since 2021/8/26 18:38
     * @param entityClass:
     * @param tableName:
     * @return java.util.List<com.franklin.java.entity.sql.ColumnInfo>
     */
    public static List<ColumnInfo> resolveColumnInEntity(PsiClass entityClass, String tableName) {
        List<ColumnInfo> mapDataList = new PrettyArrayList<>();
        Optional.ofNullable(entityClass)
            .ifPresent(psiClass -> {
                PsiField[] psiFields = psiClass.getAllFields();
                PsiCommentResolverFactory psiCommentResolverFactory = PsiCommentResolverFactory.getInstance();
                String classComment = psiCommentResolverFactory.resolveSimpleComment(psiClass);
                MPAnnotations.TableField tableFieldAnn = BaseAnnotation.get(MPAnnotations.TableField.class);
                for (PsiField psiField : psiFields) {
                    String psiFieldName = psiField.getName();
                    if (!psiFieldName.equals("serialVersionUID")) {
                        String columnName = Optional.ofNullable(psiField.getModifierList())
                            .map(psiModifierList -> psiModifierList.findAnnotation(tableFieldAnn.getQualifiedName()))
                            .map(psiAnnotation -> PsiUtils.getAnnotationAttributeValue(psiAnnotation, "value"))
                            .filter(DataCheckUtils::isNotEmpty)
                            .orElse(StringHelper.camelToUnderline(psiField.getName()));
                        ColumnInfo columnInfo = new ColumnInfo(tableName, columnName, columnName);

                        String fieldComment = psiCommentResolverFactory.resolveComment(psiField);

                        String javaType = resolveFiledType(psiField);
                        columnInfo.setComment(fieldComment);
                        columnInfo.setJavaType(javaType);
                        columnInfo.setTableComment(classComment);
                        mapDataList.add(columnInfo);
                    }
                }
            });

        return mapDataList;
    }

    public static String resolveFiledType(PsiField psiField){
        return psiField.getType().getCanonicalText();
    }

    public static String resolveFiledName(String methodName){
        if (StringHelper.isGetSetMethod(methodName)){
            String fieldName = methodName.substring(3);
            return StringHelper.camelToUnderline(StringHelper.firstToUpperCase(fieldName));
        }
        return "";
    }

    public static String resolveTableName(PsiClass entityClass) {
        return Optional.ofNullable(entityClass)
            .map(psiClass -> {
                MPAnnotations.TableName tableNameAnn = BaseAnnotation.get(MPAnnotations.TableName.class);
                return Optional.ofNullable(psiClass.getAnnotation(tableNameAnn.getQualifiedName()))
                    .map(psiAnnotation -> PsiUtils.getAnnotationAttributeValue(psiAnnotation, "value"))
                    .orElse(StringHelper.getTableName(psiClass.getName()));
            })
            .orElse("");
    }
}
